package com.saret.crawler.search;


import com.google.inject.Inject;
import com.google.inject.name.Named;
import com.saret.crawler.type.GUrl;
import com.saret.crawler.type.GUrlImpl;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.HttpURL;
import org.apache.commons.httpclient.methods.GetMethod;
import org.codebridge.translator.Language;
import org.codebridge.translator.Translator;
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Logger;

/**
 * User: biniam.gebremichael
 * Date: 2/10/11
 */
public class BingWebSearch implements WebTranslate {

    static int total = 1000;
    static int max = 50;
    static String webRequest = "http://api.bing.net/json.aspx?AppId={KEY}&Version=2.2&Market=en-US&Query={QUERY}&Sources=web&JsonType=raw&Web.Count=50&Web.offset={START}";
    static String webTranslate = "http://api.microsofttranslator.com/V2/Ajax.svc/Translate?appId={KEY}&from={FROM}&to={TO}&text={QUERY}";
    final String key;
    HttpClient client = new HttpClient();


    private static final Logger logger = Logger.getLogger(BingWebSearch.class.getName());

    @Inject
    public BingWebSearch(@Named("saret.bing.searchKeys") String key) {
        this.key = key;
    }

    public List<GUrl> search(String searchKey) {
        List<GUrl> result = new ArrayList<GUrl>();
        boolean stop = false;


        int index = 0;
        try {
            do {
                JSONObject jo = new JSONObject(internalSearch(this.key, searchKey, index)).getJSONObject("SearchResponse").getJSONObject("Web");
                JSONArray ja = jo.getJSONArray("Results");

                int resultCount = ja.length();
                index = index + resultCount;
                if (resultCount < max || index > total) {
                    stop = true;
                }
                for (int i = 0; i < resultCount; i++) {
                    JSONObject resultObject = ja.getJSONObject(i);
                    String url = resultObject.getString("Url");
                    String type = url.toLowerCase().endsWith("pdf") ? "pdf" : url.toLowerCase().endsWith("doc") ? "doc" : "html";
                    result.add(new GUrlImpl(url, 0, null, type, searchKey));
                }
            } while (!stop);

        } catch (Exception e) {
            logger.info("bing.net: no result for " + searchKey + " " + e.getMessage());
        }

        return result;
    }

    @Override
    public List<String> translate(List<String> f) {
           final Translator translator = new Translator(key);
           String[] spanishTranslation = {};
         try {
            String [] fArray = new String[f.size()];
             spanishTranslation = translator.translateArray(f.toArray( fArray), Language.ENGLISH, Language.DUTCH);
        } catch (Exception e) {
            e.printStackTrace();
        }

//        for (String s : spanishTranslation) {
//            System.out.println("s = " + s);
//        }
       return Arrays.asList(spanishTranslation);
    }

    @Override
    public String translate(String from, String to, String text) {
        String query = webTranslate.replace("{QUERY}", text).replace("{KEY}", key).replace("{TO}", to).replace("{FROM}", from);
        String jsonString = "";
        try {
            GetMethod method = new GetMethod(new HttpURL(query).getEscapedURI());
            BufferedReader br = new BufferedReader(new InputStreamReader(getStream(method)));
            String line;
            while ((line = br.readLine()) != null) {
                jsonString += line;
            }
            br.close();
            method.releaseConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonString;

    }

    public InputStream getStream(GetMethod method) throws Exception {

        // GetMethod method = new GetMethod(new HttpURL(query).getEscapedURI());
        int statusCode = client.executeMethod(method);
        if (statusCode != HttpStatus.SC_OK) {
            logger.info(" Method failed due to " + method.getStatusLine());
        }
        //  method.
        return method.getResponseBodyAsStream();
    }

    public String internalSearch(String key, String args, int index) throws Exception {

        String query = webRequest.replace("{QUERY}", args).replace("{KEY}", key).replace("{START}", String.valueOf(index));
        GetMethod method = new GetMethod(new HttpURL(query).getEscapedURI());
        BufferedReader br = new BufferedReader(new InputStreamReader(getStream(method)));
        String jsonString = "";
        String line;
        while ((line = br.readLine()) != null) {
            jsonString += line;
        }

        br.close();
        method.releaseConnection();
        return jsonString;
    }
}
